package edu.cmu.cs.stage3.scheduler;

public abstract class AbstractScheduler implements Scheduler {

 // edu.cmu.cs.stage3.alice.authoringtool.util.DefaultScheduler scheduler; edu.cmu.cs.stage3.alice.authoringtool.util.OneShotScheduler oneShotScheduler
 private java.util.Vector m_eachFrameRunnables = new java.util.Vector(); // The important runnables: in 'AuthoringTool': scheduler, oneShotScheduler
 private java.util.Vector m_eachFrameRunnablesMarkedForRemoval = new java.util.Vector();
 private Runnable[] m_cachedEachFrameRunnables;

 //public AbstractScheduler(){try{String str=""; System.out.println(str.charAt(3));}catch(Exception e){e.printStackTrace();}}

 // Add itens to be executed, from: 'edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool.AuthoringTool()' and 'void setSchedulerThread(int i)'
 // Call by: edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool.<init>(AuthoringTool.java:290, 291)
 public void addEachFrameRunnable (Runnable runnable) {
  synchronized (m_eachFrameRunnables) {
   // if (cont<10) System.out.println("AbstractScheduler.java: addEachFrameRunnable("+runnable+")");
   // try { String str=""; System.out.println(str.charAt(3));} catch (Exception e) {e.printStackTrace();}
   m_eachFrameRunnables.addElement( runnable );
   m_cachedEachFrameRunnables = null;
   }
  }

 public void markEachFrameRunnableForRemoval (Runnable runnable) {
  synchronized (m_eachFrameRunnablesMarkedForRemoval) {
   m_eachFrameRunnablesMarkedForRemoval.addElement(runnable);
   m_cachedEachFrameRunnables = null;
   }
  }

 private Runnable [] getEachFrameRunnables () {
  if (m_cachedEachFrameRunnables == null) {
//
if (cont<10) {
 System.out.println("AbstractScheduler.java: getEachFrameRunnables(): #="+m_eachFrameRunnables.size());
 for (int i=0; i<m_eachFrameRunnables.size(); i++) {
  System.out.println(" - "+i+": "+m_eachFrameRunnables.elementAt(i)); // java.util.Vector m_eachFrameRunnables
  }
 }
// AbstractScheduler.java: getEachFrameRunnables(): #=2
// - 0: edu.cmu.cs.stage3.alice.authoringtool.util.DefaultScheduler@78d278d2
// - 1: edu.cmu.cs.stage3.alice.authoringtool.util.OneShotScheduler@18f618f6
//

   synchronized (m_eachFrameRunnables) {
    synchronized (m_eachFrameRunnablesMarkedForRemoval) {
     if (m_eachFrameRunnablesMarkedForRemoval.size() > 0) {
      java.util.Enumeration enu = m_eachFrameRunnablesMarkedForRemoval.elements();
      while (enu.hasMoreElements()) {
       m_eachFrameRunnables.removeElement( enu.nextElement() );
       }
      m_eachFrameRunnablesMarkedForRemoval.clear();
      }
     m_cachedEachFrameRunnables = new Runnable[ m_eachFrameRunnables.size() ]; // runable
     m_eachFrameRunnables.copyInto( m_cachedEachFrameRunnables ); // runable <- m_eachFrameRunnables
     } // synchronized (m_eachFrameRunnablesMarkedForRemoval)
    } // synchronized (m_eachFrameRunnables)
   } // if (m_cachedEachFrameRunnables == null)
  return m_cachedEachFrameRunnables; // runable
  }

 protected abstract void handleCaughtThowable (Runnable source, Throwable t);


 // synchronized  (m_eachFrameRunnablesMarkedForRemoval) (m_eachFrameRunnables)
 //   return Runnable[] m_cachedEachFrameRunnables;

static int cont=0;
 // To run/play any program simulation
 public void run () {
  Runnable[] eachFrameRunnables = getEachFrameRunnables(); // Runnable [] m_cachedEachFrameRunnables - copy of 'm_eachFrameRunnables'
  Runnable eachFrameRunnable = null;
  int t_tam = eachFrameRunnables!=null ? eachFrameRunnables.length : 0; //L
  // if (cont==0)System.out.println("AbstractScheduler.java: run(): #eachFrameRunnables="+t_tam);

  // for all comands - run constantly
  //L for (Runnable eachFrameRunnable : eachFrameRunnables) //L this version doesn't work under Java < 5
  for (int i_i=0; i_i<t_tam; i_i++) { //L
    try { // 'eachFrameRunnable' in 'edu.cmu.cs.stage3.alice.authoringtool.util.DefaultScheduler'
      eachFrameRunnable = eachFrameRunnables[i_i]; //L
      // if (cont==0)System.out.println("AbstractScheduler.java: run(): "+i_i+": "+eachFrameRunnable+"");

      eachFrameRunnable.run();

    } catch (Throwable t) {
      System.err.println("Error: AbstractScheduler.java: run(): "+eachFrameRunnable+": "+t.toString()+""); // t.printStackTrace();
      handleCaughtThowable(eachFrameRunnable, t);
      }
    }
  } // void run()

 } // public abstract class AbstractScheduler implements Scheduler
